﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Management;
using System.Runtime.Serialization;
using AutonomicComputingLibrary.Utils.StateManagement;
using AutonomicComputingLibrary.MAPE;

namespace AutonomicComputingLibrary.LogicalSensors
{

   

    [Serializable()]
    public class RAMManagement :  ISerializable
    {

        //should we also look at virtual memrory?

        public uint TotalMBRAM { get; set; }

        public int UsagePercentage { get; set; }

        public int PercentageMin { get; set; }

        public int PercentageMax { get; set; }

        private static RAMManagement instance;

       


 


        static List<Tuple<Health, string>> HealthHistory = new List<Tuple<Health, string>>();


        /// <summary>
        /// Construct a RAM manager
        /// </summary>
        /// <param name="MaxMemPercent"></param>
        /// <param name="MinMemPercent"></param>
        public RAMManagement(int MaxMemPercent = 99, int MinMemPercent = 1)
        {
            PercentageMin = MinMemPercent;
            PercentageMax = MaxMemPercent;

            var Query = "SELECT MaxCapacity FROM Win32_PhysicalMemoryArray";
            var searcher = new ManagementObjectSearcher(Query);

            //get total ram in MB
            foreach (var item in searcher.Get())
                TotalMBRAM = Convert.ToUInt32(item.Properties["MaxCapacity"].Value) /
                1024;

           

        }

        public event AlertHandler Alert;

        public void CheckUp()
        {


            while (true)
            {
                System.Threading.Thread.Sleep(3000);
                if (Check() == Health.Negative)
                {
                    ACLAlert aclal = new ACLAlert();
                    aclal.Alert = Health.Negative.ToString();
                    Alert(this, aclal);

                  
                }
            }
        }
        /// <summary>
        /// Determine if the RAM on system is healthy. This can also be null.
        /// </summary>
        /// <returns></returns>

         Health? Check()
        {
           
            try
            {
                

                PerformanceCounter ramCounter = new PerformanceCounter("Memory", "Available MBytes");

               
                var mem =  ((TotalMBRAM - (ramCounter.NextValue())) / 100);

                return mem > PercentageMax || mem < PercentageMin
                           ? Health.Negative
                           : Health.Positive;
            }
            catch
            {
              
                return Health.UnableToDetermine;
            }
        }
      

        //return singleton

        public static RAMManagement Instance(int MaxMem = 99, int MinMem = 1)
        {
                     
            return instance ?? (instance = new RAMManagement(MaxMem, MinMem));

        }
       

        public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
        {
            info.AddValue("TotalMBRAM", this.TotalMBRAM);
            info.AddValue("UsagePercentage", this.UsagePercentage);

            info.AddValue("PercentageMin", this.PercentageMin);
            info.AddValue("PercentageMax", this.PercentageMax);
           
            info.AddValue("instance", instance);
           info.AddValue("HealthHistory", HealthHistory);           

        }
    }
}
